import {Component, ElementRef, OnDestroy, OnInit, ViewChild} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import { MarkdownService } from 'ngx-markdown';
import {NzMessageService} from 'ng-zorro-antd/message';
import {trigger, state, style, animate, transition, } from '@angular/animations';
import {NzUploadChangeParam, NzUploadFile} from 'ng-zorro-antd/upload';
import {NzModalService} from 'ng-zorro-antd/modal';
import {HttpClient, HttpRequest, HttpResponse } from '@angular/common/http';
import { filter } from 'rxjs/operators';

import {ArticleInterface, ArticlesManagerService} from '../../manager-business/articles-manager.service';
import {ComponentViewEnm, ComponetViewManagerService} from '../../../business/componet-view-manager.service';
import {Subscription} from 'rxjs';
import {ArticleService} from '../../services/article.service';


function getBase64(file: File): Promise<string | ArrayBuffer | null> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

@Component({
  selector: 'app-article-create',
  templateUrl: './article-create.component.html',
  styleUrls: ['./article-create.component.css'],
  providers: [ MarkdownService, ArticleService ],
  animations:[
    // 可以设置多个动画
    trigger('showPreviewBox',
      [
        state('hide', style({
          transform: 'scale(0)',
          opacity: 0,
          background: 'white'
      })),
      state('show', style({
        transform: 'scale(1)',
        opacity: 1
      })),
      // 设置从一个状态到另外一个状态的运动效果，非必填字段
      transition('hide=>show', animate('1000ms ease-in')),
      transition('show=>hide', animate('500ms ease-out')),
    ])]
})
export class ArticleCreateComponent implements OnInit, OnDestroy {
  public viewName = ComponentViewEnm.ARTICLECREATE;
  public uploadUrl = `${$_serverPath}/admin/articles/uploads/cover`;
  public uploadFileType = 'image/png,image/jpeg,image/gif,image/bmp';
  public uploading = false;
  private isDirty = false;  // 脏
  inputVisible = false;
  inputValue = '';
  @ViewChild('inputElement', { static: false }) inputElement?: ElementRef;
  public article: ArticleInterface = {
    id: -1,
    user_id: 0,
    type: '1',
    article_title: '',
    cover_img_url: [],
    article_categorys: [],
    article_content: '',
    article_des: '',
    article_views: 0,
    article_date: +new Date(),
    last_edit_date: +new Date()
  };
  public showText: string; // 展示文本
  public previewImage: string | undefined = '';
  public previewVisible = false;

  constructor(
    private articlesManagerService: ArticlesManagerService,
    private message: NzMessageService,
    private activatedRoute: ActivatedRoute,
    private router: Router,
    private modal: NzModalService,
    public CVMS: ComponetViewManagerService,
    private markdownService: MarkdownService,
    private http: HttpClient
  ) { }

  ngOnInit(): void {
    this.CVMS.setCurrentView(this.viewName);
    const params: any = this.activatedRoute.params;
    const id = params.value && params.value.id;
    if (id) {
      if (this.articlesManagerService.articles.length) {
        // 缓存中存在
        this.articlesManagerService.getArticleDetail(Number(id), (res) => {
          this.article = this.responseDataHanle(res);
        });
      } else {
        // 缓存中不存在
        const temp = this.articlesManagerService.articlesChange.subscribe({next: (res) => {
            this.articlesManagerService.getArticleDetail(Number(id), (res: ArticleInterface) => {
              this.article = this.responseDataHanle(res);
            });
            temp.unsubscribe();
        }});
      }
    }
  }

  ngOnDestroy(): void {
    this.CVMS.destroyCurrentView(this.viewName);
  }

  beforeUpload = (file: NzUploadFile): boolean => {
    this.article.cover_img_url = this.article.cover_img_url.concat(file);
    return true;
  }

  public handleUpload = (): Subscription =>  {
    const formData = new FormData();
    // tslint:disable-next-line:no-any
    this.article.cover_img_url.forEach((file: any) => {
      formData.append('file', file);
    });
    this.uploading = true;
    // You can use any AJAX library you like
    const req = new HttpRequest('POST', `${$_serverPath}/admin/articles/uploads/cover`, formData, {
      // reportProgress: true
    });
    return this.http
      .request(req)
      .pipe(filter(e => e instanceof HttpResponse))
      .subscribe(
        (res) => {
          const result: any = res;
          const data = result.body || {};
          const file: NzUploadFile =  {
              uid: undefined,
              name:  data.content.name,
              status: 'done',
              url: `${$_serverPath}/${data.content.url}`
           };
          this.uploading = false;
          this.article.cover_img_url.splice(0);
          this.article.cover_img_url = this.article.cover_img_url.concat(file);
          this.message.success('upload successfully.');
        },
        () => {
          this.uploading = false;
          this.message.error('upload failed.');
        });
  }

  public createArticle(): void {
    const date = +new Date();
    if (this.article.id !== -1) {
      // 编辑
      this.article.last_edit_date = date;
      this.articlesManagerService.updateArticle(this.article);
    } else {
      // 新增
      this.article.article_date = date;
      this.article.last_edit_date = date;
      this.articlesManagerService.addArticle(this.article);
    }
    this.isDirty = false;
  }

  handleChange({ file, fileList }: NzUploadChangeParam): void {
    const status = file.status;
    if (status !== 'uploading') {
      console.log(file, fileList);
    }
    if (status === 'done') {
      this.message.success(`${file.name} file uploaded successfully.`);
    } else if (status === 'error') {
      this.message.error(`${file.name} file upload failed.`);
    }
  }

  contentChange(e): void {
    this.article.article_content = e;
    this.showText = this.markdownService.compile(e);
    this.isDirty = true;
  }


  handleClose(removedTag: {}): void {
    this.article.article_categorys = this.article.article_categorys.filter(tag => tag !== removedTag);
  }

  sliceTagName(tag: string): string {
    const isLongTag = tag.length > 20;
    return isLongTag ? `${tag.slice(0, 20)}...` : tag;
  }

  showInput(): void {
    this.inputVisible = true;
    setTimeout(() => {
      this.inputElement?.nativeElement.focus();
    }, 10);
  }

  handleInputConfirm(): void {
    if (this.inputValue && this.article.article_categorys.indexOf(this.inputValue) === -1) {
      this.article.article_categorys = [...this.article.article_categorys, this.inputValue];
    }
    this.inputValue = '';
    this.inputVisible = false;
  }

  private responseDataHanle(res: ArticleInterface): ArticleInterface {
    const article_categorys: any = res.article_categorys;
    const coverImgUrl: any = res.cover_img_url;
    if (typeof article_categorys === 'string') {
      res.article_categorys = article_categorys.split(',');
    }
    try {
      res.cover_img_url = JSON.parse(coverImgUrl);
    } catch (e) { console.log(e); }
    if (!(res.cover_img_url instanceof Array)) {
      res.cover_img_url = [];
    }
    return res;
  }

  public goBack(): void {
    if (!this.isDirty) {
      this.router.navigateByUrl('/main/manager');
      return;
    }
    this.modal.confirm({
      nzTitle: '您是否确认返回?',
      nzContent: '当前编辑內容未发布， 将丢弃。',
      nzOkText: '是',
      nzOkType: 'default',
      nzOnOk: () => {
        this.router.navigateByUrl('/main/manager');
      },
      nzCancelText: '否',
      nzOnCancel: () => console.log('Cancel')
    });
  }

  handlePreview = async (file: NzUploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj!);
    }
    this.previewImage = file.url || file.preview;
    this.previewVisible = true;
  }

  public checkedCoverImgLen(): boolean {
    if (!this.article.cover_img_url || this.article.cover_img_url.length < 1) {
      return true;
    }
    return false;
  }
}
